/*
 * PublicRRDTool.cpp
 *
 *  Created on: 2017-3-30
 *      Author: root
 */
#include"PublicRRDTool.h"
#include"PublicLog.h"
#include"PublicTool.h"
#if USE_PUBLIC_RRD
//#define _RRD_TOOL_H
#ifdef _RRD_TOOL_H
#define RRD_READONLY    (1<<0)
#define RRD_READWRITE   (1<<1)
#define RRD_CREAT       (1<<2)
#define RRD_READAHEAD   (1<<3)
#define RRD_COPY        (1<<4)
#endif
#ifdef __MINGW32__
//否则nan输出有问题
#include<cstdlib>
#endif
#include<rrd.h>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<string.h>

int CreateEmptyRRDTool(const char*RRDName,const char*DS1Name,const char*DS2Name){
    char str1[100]={0};
    char str2[100]={0};
    char str3[100]={0};
    char str4[100]={0};
    const char*argv[4]={str1,str2,str3,str4};
    sprintf(str1,"DS:%s:GAUGE:%lu:U:U",DS1Name,300UL);
    if(DS2Name==NULL){
        sprintf(str2,"RRA:AVERAGE:0.5:1:288");
        sprintf(str3,"RRA:MAX:0.5:1:288");
        if(rrd_create_r(RRDName,300,0,3,argv)!=0){
          WRONG("CreateRRDTool:%s Err:%s",RRDName,rrd_get_error());
          rrd_clear_error();
          return -1;
        }
    }else{
        sprintf(str2,"DS:%s:GAUGE:%lu:U:U",DS2Name,300UL);
        sprintf(str3,"RRA:AVERAGE:0.5:1:288");
        sprintf(str4,"RRA:MAX:0.5:1:288");
        if(rrd_create_r(RRDName,300,0,4,argv)!=0){
          WRONG("CreateRRDTool:%s Err:%s",RRDName,rrd_get_error());
          rrd_clear_error();
          return -1;
        }
    }
    return 0;
}

int CreateRRDFileByData(const char*RRDName,RRDDateInfo*info){
    if(info->ds_cnt==1){
        char DSDescr[128]={0};
        char RRADescrAVG[128]={0};
        char RRADescrMAX[128]={0};
        const char*argv[3]={
        DSDescr,
        RRADescrAVG,
        RRADescrMAX};
        sprintf(DSDescr,"DS:%s:GAUGE:%lu:U:U",info->ds_namv[0],info->step);
        sprintf(RRADescrAVG,"RRA:AVERAGE:0.5:1:%lu",info->steps);
        sprintf(RRADescrMAX,"RRA:MAX:0.5:1:%lu",info->steps);
        if(rrd_create_r(RRDName,info->step,info->start_tm,3,argv)!=0){
			WRONG("CreateRRDTool:%s Err:%s",RRDName,rrd_get_error());
			rrd_clear_error();
			return -1;
        }
    }else
    if(info->ds_cnt==2){
        char DS1Descr[128]={0};
        char DS2Descr[128]={0};
        char RRADescrAVG[128]={0};
        char RRADescrMAX[128]={0};
        const char*argv[4]={
        DS1Descr,
        DS2Descr,
        RRADescrAVG,
        RRADescrMAX};
        sprintf(DS1Descr,"DS:%s:GAUGE:%lu:U:U",info->ds_namv[0],info->step);
        sprintf(DS2Descr,"DS:%s:GAUGE:%lu:U:U",info->ds_namv[1],info->step);
        sprintf(RRADescrAVG,"RRA:AVERAGE:0.5:1:%lu",info->steps);
        sprintf(RRADescrMAX,"RRA:MAX:0.5:1:%lu",info->steps);
        if(rrd_create_r(RRDName,info->step,info->start_tm,4,argv)!=0){
			WRONG("CreateRRDTool:%s Err:%s",RRDName,rrd_get_error());
			rrd_clear_error();
			return -1;
        }
    }else{
        return -1;
    }
   return 0;
}
#define RRD_UPDATE_MAXNUM 1000
int CreateRRDToolByData(const char*RRDName,RRDDateInfo*info){
    if(CreateRRDFileByData(RRDName,info)!=0)
		return -1;
    unsigned long i=0;
    while(i<info->steps){
		int j=0;
		char buff[RRD_UPDATE_MAXNUM][100]={{0}};
		const char*data[RRD_UPDATE_MAXNUM];
		while((j<RRD_UPDATE_MAXNUM)&&(i<info->steps)){
			if(info->ds_cnt==1){
				sprintf(buff[j],"%ld:%f",info->start_tm+(i+1)*info->step,info->data[i]);
			}else{
				sprintf(buff[j],"%ld:%f:%f",info->start_tm+(i+1)*info->step,
				info->data[i*info->ds_cnt+0],info->data[i*info->ds_cnt+1]);
			}
			data[j]=buff[j];
			j++;
			i++;
		}
		if(rrd_update_r(RRDName,NULL,j,data)!=0){
			WRONG("rrd_update_r %s",rrd_get_error());
			rrd_clear_error();
			return -1;
        }
    }
    return 0;
}

time_t GetRRDFirstTime(const char*RRDName){
	return rrd_first_r(RRDName,0);
}
time_t GetRRDLastTime(const char*RRDName){
	return rrd_last_r(RRDName);
}
/*
int       rrd_fetch_r(
const char *filename,
const char *cf,
time_t *start,
time_t *end,
unsigned long *step,
unsigned long *ds_cnt,
char ***ds_namv,
rrd_value_t **data);*/

RRDDateInfo*GetRRDData(const char*RRDName,time_t starttime,time_t endtime){
	RRDDateInfo*pRRDInfo=(RRDDateInfo*)malloc(sizeof(RRDDateInfo));
	memset(pRRDInfo,0,sizeof(RRDDateInfo));
	pRRDInfo->start_tm=starttime;
	pRRDInfo->end_tm=endtime;
	pRRDInfo->step=300;
//第一个时间戳不算
	if(rrd_fetch_r(RRDName,"AVERAGE",&pRRDInfo->start_tm,&pRRDInfo->end_tm,&pRRDInfo->step,&pRRDInfo->ds_cnt,&pRRDInfo->ds_namv,&pRRDInfo->data)!=0){
		WRONG("LINE:%d %s",__LINE__,rrd_get_error());
		rrd_clear_error();
		FreeRRDData(pRRDInfo);
		return NULL;
	}
	if(pRRDInfo->step>0){
		pRRDInfo->steps=(pRRDInfo->end_tm-pRRDInfo->start_tm)/pRRDInfo->step;
	}
	return pRRDInfo;
}
void ShowRRDData(RRDDateInfo*RRDInfo){
	if(RRDInfo==NULL)return;
	printf("RRDDate Start:%ld End:%ld Step:%lu Steps:%lu DsCnt:%lu\n",
		RRDInfo->start_tm,RRDInfo->end_tm,RRDInfo->step,RRDInfo->steps,RRDInfo->ds_cnt);
	unsigned long i=0;
	while(i<RRDInfo->ds_cnt){
		printf("\t\t%s",RRDInfo->ds_namv[i]);
		i++;
	}
	printf("\n");
	i=0;
	while(i<RRDInfo->steps){
		printf("NO[%3lu]%ld:",i,RRDInfo->start_tm+(i+1)*RRDInfo->step);
		unsigned long j=0;
		while(j<RRDInfo->ds_cnt){
			printf("\t%8.4f",RRDInfo->data[i*RRDInfo->ds_cnt+j]);
			j++;
		}
		printf("\n");
		i++;
	}
}
void FreeRRDData(RRDDateInfo*RRDInfo){
	if(RRDInfo==NULL)return;
	unsigned long i=0;
	for(i=0;i<RRDInfo->ds_cnt;i++){
		rrd_freemem(RRDInfo->ds_namv[i]);
	}
	if(RRDInfo->ds_cnt>0)
		rrd_freemem(RRDInfo->ds_namv);
	if(RRDInfo->data)
		rrd_freemem(RRDInfo->data);
	free(RRDInfo);
}
double GetRRDData95ValuesFromFile(const char*rrdname,time_t start,time_t end,int bCacti);
void GraphRRDData(const char*pngname,const char*rrdname,const char*dtsname,time_t start,time_t end,const char*title,int bits,int useavg){
    char PNGName[256]={0};
    char StartTime[32]={0};
    char EndTime[32]={0};
    char Title[256]={0};
    char DataDEF[256]={0};
    char DataCDEF[256]={0};
    char DescrArea[256]={0};
    char DescrLine[256]={0};
    char HRULE95[256]={0};
    char COMMENT95[256]={0};
    double val95th=GetRRDData95ValuesFromFile(rrdname,start,end,0);
    strcpy(PNGName,pngname);
    sprintf(StartTime,"--start=%ld",start);
    sprintf(EndTime,"--end=%ld",end);
    sprintf(Title,"--title=%s",title);
	if(useavg){
		sprintf(DataDEF,"DEF:a=%s:%s:AVERAGE",rrdname,dtsname);
	}else{
		sprintf(DataDEF,"DEF:a=%s:%s:MAX",rrdname,dtsname);
	}
    sprintf(DataCDEF,"CDEF:cdefa=a,%d,*",bits==0?1:bits);
    sprintf(DescrArea,"AREA:cdefa#00CF00FF:%s","Inbound ");
    sprintf(DescrLine,"LINE1:cdefa#002A97FF:%s","Outbound");
    sprintf(HRULE95,"HRULE:%0.2f#FF0000FF:95%%",val95th*bits);
    sprintf(COMMENT95,"COMMENT:(%0.2f mbit in+out)\\n",val95th*bits/1000000);
    const char*data[]={
    "graphv",
    PNGName,
    "--imgformat=PNG",
    StartTime,
    EndTime,
    Title,
    "--rigid",
    "--base=1000",
    "--height=120",
    "--width=500",
    "--alt-autoscale-max",
    "--lower-limit=0",
    "--vertical-label=bits per second",
    "--slope-mode",
    "--font",
    "TITLE:10:",
    "--font",
    "AXIS:7:",
    "--font",
    "LEGEND:8:",
    "--font",
    "UNIT:7:",
    DataDEF,
    DataCDEF,
//  "VDEF:cdefx=cdefa,95,PERCENT",
    DescrArea,
    "GPRINT:cdefa:LAST:Current\\:%8.2lf %s",
    "GPRINT:cdefa:AVERAGE:Average\\:%8.2lf %s",
    "GPRINT:cdefa:MAX:Maximum\\:%8.2lf %s\\n",
    DescrLine,
    "GPRINT:cdefa:LAST:Current\\:%8.2lf %s",
    "GPRINT:cdefa:AVERAGE:Average\\:%8.2lf %s",
    "GPRINT:cdefa:MAX:Maximum\\:%8.2lf %s\\n",
//  "HRULE:cdefx#FF0000FF:95%",
//  "GPRINT:vdefx:(%8.2lf %s in)\\n"
    HRULE95,
    COMMENT95
    };
    rrd_info_t *grinfo = NULL;
    grinfo = rrd_graph_v(sizeof(data)/sizeof(void*),(char**)data);
    if(grinfo){
		rrd_info_free(grinfo);
    }else{
		WRONG("LINE:%d %s",__LINE__,rrd_get_error());
		rrd_clear_error();
    }
}

void GraphRRDDataFlow(const char*pngname,const char*rrdname,time_t start,time_t end,const char*title,int bits){
	char PNGName[256]={0};
	char StartTime[32]={0};
	char EndTime[32]={0};
	char Title[256]={0};
	char DataDEFA[256]={0};
	char DataDEFB[256]={0};
	char DataCDEFA[256]={0};
	char DataCDEFB[256]={0};
	strcpy(PNGName,pngname);
	sprintf(StartTime,"--start=%ld",start);
	sprintf(EndTime,"--end=%ld",end);
	sprintf(Title,"--title=%s",title);
	sprintf(DataDEFA,"DEF:a=%s:traffic_in:MAX",rrdname);
	sprintf(DataDEFB,"DEF:b=%s:traffic_out:MAX",rrdname);
	sprintf(DataCDEFA,"CDEF:cdefa=a,%d,*",bits==0?1:bits);
	sprintf(DataCDEFB,"CDEF:cdefb=b,%d,*",bits==0?1:bits);
	const char *data[]={
	"graphv",
	PNGName,
	"--imgformat=PNG",
	StartTime,
	EndTime,
	Title,
	"--rigid",
	"--base=1000",
	"--height=120",
	"--width=500",
	"--alt-autoscale-max",
	"--lower-limit=0",
	"--vertical-label=bits per second",
	"--slope-mode",
	"--font",
	"TITLE:10:",
	"--font",
	"AXIS:7:",
	"--font",
	"LEGEND:8:",
	"--font",
	"UNIT:7:",
	DataDEFA,
	DataDEFB,
	DataCDEFA,
	DataCDEFB,
	"VDEF:vdefa=cdefa,95,PERCENT",
	"VDEF:vdefb=cdefb,95,PERCENT",
	"AREA:cdefa#00CF00FF:Inbound ",
	"GPRINT:cdefa:LAST:Current\\:%8.2lf %s",
	"GPRINT:cdefa:AVERAGE:Average\\:%8.2lf %s",
	"GPRINT:cdefa:MAX:Maximum\\:%8.2lf %s\\n",
	"LINE1:cdefb#002A97FF:Outbound",
	"GPRINT:cdefb:LAST:Current\\:%8.2lf %s",
	"GPRINT:cdefb:AVERAGE:Average\\:%8.2lf %s",
	"GPRINT:cdefb:MAX:Maximum\\:%8.2lf %s\\n",
	"HRULE:vdefa#FF0000FF:95%",
	"GPRINT:vdefa:(%8.2lf %s in)\\n",
	"HRULE:vdefb#FF00FFFF:95%",
	"GPRINT:vdefb:(%8.2lf %s out)\\n"
	};
    rrd_info_t *grinfo = NULL;
    grinfo = rrd_graph_v(sizeof(data)/sizeof(void*),(char**)data);
    if(grinfo){
		rrd_info_free(grinfo);
    }else{
		WRONG("%s",rrd_get_error());
		rrd_clear_error();
    }      
}
#include<math.h>
//从小到大排序
int vdef_percent_compar(const void*a,const void*b){
    if (isnan(*(double *) a))return -1;
    if (isnan(*(double *) b))return 1;
    if (isinf(*(double *) a))return isinf(*(double *) a);
    if (isinf(*(double *) b))return isinf(*(double *) b);
    if (*(double *) a < *(double *) b)
        return -1;
    else
        return 1;
}
//从大到小排序
int vdef_percent_compar_ex(const void*a,const void*b){
    if (isnan(*(double *) a))return 1;
    if (isnan(*(double *) b))return -1;
    if (isinf(*(double *) a))return isinf(*(double *) a);
    if (isinf(*(double *) b))return isinf(*(double *) b);
    if (*(double *) a < *(double *) b)
        return 1;
    else
        return -1;
}
//Cacti的95算法
double GetRRDData95ValuesCacti(RRDDateInfo*rrdinfo){
    double value=0.0;
    if(rrdinfo->steps<1)return value;
    //int Pos=0.05*(rrdinfo->steps+1);
    //printf("Time:%ld~%ld Total:%lu+1 Pos:%d\n",rrdinfo->start_tm,rrdinfo->end_tm,rrdinfo->steps,Pos);
    double*array=(double*)malloc(sizeof(double)*rrdinfo->steps);
    unsigned long i=0;
    while(i<rrdinfo->ds_cnt){
		double tmp=0.0;
		unsigned long j=0;
		int alivenum=0;
		while(j<rrdinfo->steps){
			array[j]=rrdinfo->data[j*rrdinfo->ds_cnt+i];
			if(array[j]>0)alivenum++;
			j++;
        }
		qsort(array,rrdinfo->steps,sizeof(double),vdef_percent_compar_ex);
		int Pos=0.05*(alivenum+1);
		tmp=array[Pos];
		if(tmp>value)value=tmp;
		i++;
    }
    free(array);
    return value;
}
//EM95算法
//最后一个点不参与计算
double GetRRDData95ValuesEM(RRDDateInfo*rrdinfo){
    double value=0.0;
    if(rrdinfo->steps<2)return value;
    int Pos=0.05*(rrdinfo->steps-1);
    double*array=(double*)malloc(sizeof(double)*(rrdinfo->steps-1));
    unsigned long i=0;
    while(i<rrdinfo->ds_cnt){
		double tmp=0.0;
		unsigned long j=0;
		while(j<(rrdinfo->steps-1)){
			array[j]=rrdinfo->data[j*rrdinfo->ds_cnt+i];
			j++;
        }
		qsort(array,rrdinfo->steps-1,sizeof(double),vdef_percent_compar_ex);
		tmp=array[Pos];
#if 0
		do{
			int k=Pos-5;
			if(k<0)k=0;
			while(k<(Pos+5)){
				printf("k:%d %0.2f\n",k,array[k]);
				k++;
			}
			printf("Time:%ld~%ld Total:%lu-1 Pos:%d\n",rrdinfo->start_tm,rrdinfo->end_tm,rrdinfo->steps,Pos);
			printf("Pos:%d %0.2f\n",Pos,tmp);
		}while(0);
#endif
		if(tmp>value)value=tmp;
		i++;
    }
    free(array);
    return value;
}

void auto_scale(double *value,const char **symb_ptr,double *magfact){
    const char     *symbol[] = { 
		"a",			/* 10e-18 Atto */
        "f",            /* 10e-15 Femto */
        "p",            /* 10e-12 Pico */
        "n",            /* 10e-9  Nano */
        "u",            /* 10e-6  Micro */
        "m",            /* 10e-3  Milli */
        " ",            /* Base */
        "k",            /* 10e3   Kilo */
        "M",            /* 10e6   Mega */
        "G",            /* 10e9   Giga */
        "T",            /* 10e12  Tera */
        "P",            /* 10e15  Peta */
        "E"
    };                  /* 10e18  Exa */

    int       symbcenter = 6;
    int       sindex;

    if (*value == 0.0 || isnan(*value)) {
        sindex = 0;
        *magfact = 1.0;
    } else {
        sindex = floor(log(fabs(*value)) / log((double) 1000));
        *magfact = pow((double) 1000, (double) sindex);
        (*value) /= (*magfact);
    }
    if (sindex <= symbcenter && sindex >= -symbcenter) {
        (*symb_ptr) = symbol[sindex + symbcenter];
    } else {
        (*symb_ptr) = "?";
    }
}


double GetRRDData95ValuesFromFile(const char*rrdname,time_t start,time_t end,int bCacti){
    double value=0.0;
    RRDDateInfo*rrdinfo=GetRRDData(rrdname,start,end);
    if(rrdinfo!=NULL&&rrdinfo->steps>0){
		if(bCacti)
			value=GetRRDData95ValuesCacti(rrdinfo);
		else
			value=GetRRDData95ValuesEM(rrdinfo);
    }
    FreeRRDData(rrdinfo);
    return value;
}

void GetRRDDataAVGValuesFromFile(const char*rrdname,time_t start,time_t end,double*values1,double*values2){
	RRDDateInfo*rrdinfo=GetRRDData(rrdname,start,end);
	if(rrdinfo!=NULL&&rrdinfo->steps>0){
		unsigned long i=0;
		while(i<rrdinfo->ds_cnt){
			double tmp=0.0;
			int    cnt=0;
			unsigned long j=0;
			while(j<(rrdinfo->steps-1)){
				if(isnan(rrdinfo->data[j*rrdinfo->ds_cnt+i])||
				   isinf(rrdinfo->data[j*rrdinfo->ds_cnt+i])||
					(rrdinfo->data[j*rrdinfo->ds_cnt+i]==0.0)){
				}else{
					tmp+=rrdinfo->data[j*rrdinfo->ds_cnt+i];
					cnt++;
				}
				j++;
			}
			if(cnt>0)tmp/=cnt;
			if(i==0)*values1=tmp;
			if(i==1)*values2=tmp;
			i++;
		}
	}
	FreeRRDData(rrdinfo);
}

void GraphRRDDataFlowEx(const char*pngname,const char*rrdname,time_t start,time_t end,const char*title,int bits,int useavg){
    char PNGName[256]={0};//testday95.png
    char StartTime[32]={0};
    char EndTime[32]={0};
    char Title[256]={0};
    char DataDEFA[256]={0};
    char DataDEFB[256]={0};
    char DataCDEFA[256]={0};
    char DataCDEFB[256]={0};
	char DataAvgA[256]={0};
    char DataAvgB[256]={0};
    char HRULE95[256]={0};
    char COMMENT95[256]={0};
    double val95th=GetRRDData95ValuesFromFile(rrdname,start,end,0);
    strcpy(PNGName,pngname);
    sprintf(StartTime,"--start=%ld",start);
    sprintf(EndTime,"--end=%ld",end);
    sprintf(Title,"--title=%s",title);
	sprintf(DataDEFA,"DEF:a=%s:traffic_in:MAX",rrdname);
	sprintf(DataDEFB,"DEF:b=%s:traffic_out:MAX",rrdname);
    sprintf(DataCDEFA,"CDEF:cdefa=a,%d,*",bits==0?1:bits);
    sprintf(DataCDEFB,"CDEF:cdefb=b,%d,*",bits==0?1:bits);
//  平均值方式
	if(useavg){
		double val1=0.0;
		double val2=0.0;
		double RealVal1=0;
		double RealVal2=0;
		const char*Descr1=NULL;
		const char*Descr2=NULL;
		GetRRDDataAVGValuesFromFile(rrdname,start,end,&val1,&val2);
		if(bits>1){
			val1*=bits;
			val2*=bits;
		}
		auto_scale(&val1,&Descr1,&RealVal1);
		auto_scale(&val2,&Descr2,&RealVal2);
		sprintf(DataAvgA,"COMMENT:Average\\:%8.2lf %s",val1,Descr1);
		sprintf(DataAvgB,"COMMENT:Average\\:%8.2lf %s",val2,Descr2);	
	}else{
		sprintf(DataAvgA,"GPRINT:cdefa:AVERAGE:Average\\:%%8.2lf %%s");
		sprintf(DataAvgB,"GPRINT:cdefb:AVERAGE:Average\\:%%8.2lf %%s");	
	}
//  95值样式	
//  HRULE:337735252.94#FF0000FF:"95%"
//  COMMENT:"(337.74 mbit in+out)\n"	
    sprintf(HRULE95,"HRULE:%0.2f#FF0000FF:95%%",val95th*bits);
    sprintf(COMMENT95,"COMMENT:(%0.2f mbit in+out)\\n",val95th*bits/1000000);
    const char *data[]={
    "graphv",
    PNGName,
    "--imgformat=PNG",
    StartTime,
    EndTime,
    Title,
    "--rigid",
    "--base=1000",
    "--height=120",
    "--width=500",
    "--alt-autoscale-max",
    "--lower-limit=0",
    "--vertical-label=bits per second",
    "--slope-mode",
    "--font",
    "TITLE:10:",
    "--font",
    "AXIS:7:",
    "--font",
    "LEGEND:8:",
    "--font",
    "UNIT:7:",
    DataDEFA,
    DataDEFB,
    DataCDEFA,
    DataCDEFB,
    "AREA:cdefa#00CF00FF:Inbound ",
    "GPRINT:cdefa:LAST:Current\\:%8.2lf %s",
	DataAvgA,
    "GPRINT:cdefa:MAX:Maximum\\:%8.2lf %s\\n",
    "LINE1:cdefb#002A97FF:Outbound",
    "GPRINT:cdefb:LAST:Current\\:%8.2lf %s",
    DataAvgB,
    "GPRINT:cdefb:MAX:Maximum\\:%8.2lf %s\\n",
    HRULE95,
    COMMENT95
    };
    rrd_info_t *grinfo = NULL;
    grinfo = rrd_graph_v(sizeof(data)/sizeof(void*),(char**)data);
    if(grinfo){
		//rrd_info_print(grinfo);
		rrd_info_free(grinfo);
    }else{
		WRONG("%s",rrd_get_error());
		rrd_clear_error();
    }
}

int CreateTrafficRRDTool(const char*RRDName,time_t starttime){
//最多保留100天数据	
	const char*data[10]={
	"DS:traffic_in:COUNTER:600:0:10000000000",
	"DS:traffic_out:COUNTER:600:0:10000000000",
    "RRA:AVERAGE:0.5:1:28800",
	"RRA:AVERAGE:0.5:6:4800",
	"RRA:AVERAGE:0.5:24:1200",
	"RRA:AVERAGE:0.5:288:100",
    "RRA:MAX:0.5:1:28800",
	"RRA:MAX:0.5:6:4800",
	"RRA:MAX:0.5:24:1200",
	"RRA:MAX:0.5:288:100"};
	if(rrd_create_r(RRDName,300,starttime,10,data)!=0){
	    WRONG("%s",rrd_get_error());
	    rrd_clear_error();
		return -1;
	}
	return 0;
}
int UpdateTrafficRRDTool(const char*RRDName,time_t timestamp,uint64_t ifHCInOctets,uint64_t ifHCOutOctets){
	char buff[1024]={0};
	sprintf(buff,"%ld:" PRU64 ":" PRU64,timestamp,ifHCInOctets,ifHCOutOctets);
	//printf("%s\n",buff);
	const char*data[20];
	data[0]=buff;
	if(rrd_update_r(RRDName,NULL,1,data)!=0){
	    WRONG("%s",rrd_get_error());
	    rrd_clear_error();
		return -1;
	}
	return 0;
}
int GraphTrafficRRDTool(const char*pngname,const char*rrdname,time_t starttime,time_t endtime){
	GraphRRDDataFlow(pngname,rrdname,starttime,endtime,NULL,8);
	return 0;
}
#endif
